package pe.com.trestperu.common.model.dao;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import pe.com.trestperu.common.exception.CoreDBException;


/**
 * GenericDAO Interface to access to Database
 *
 * @author Telly Tataje
 *
 */
public interface GenericDAO {

	/**
	 * return sql connection current instance from Hibernate
	 * 
	 * @return Connection
	 * @throws CoreDBException
	 */
	public Connection getConnection() throws CoreDBException;

	/**
	 * method to persist object in database this method use
	 * saveOrUpdate Hibernate method to persist object.
	 * 
	 * @param object
	 * @throws CoreDBException
	 */
    public void save(Object object) throws CoreDBException;

    /**
     * method to delete object from database
     * 
     * @param persistentInstance
     * @throws CoreDBException
     */
    public void delete(Object persistentInstance) throws CoreDBException;

    /**
     * method to find object for Hibernate Id
     * 
     * @param clazz
     * @param id
     * @return Object
     * @throws CoreDBException
     */
    public Object findById(Class<?> clazz, Serializable id) throws CoreDBException;

    /**
     * Method to get list from object using findByExample Hibernate method.
     * 
     * @param object
     * @return List
     * @throws CoreDBException
     */
    public List<?> findByObject(Object object) throws CoreDBException;

    /**
     * Method to delete object from Id, this method use findById to get object instance
     * and delete to perform action in database
     * 
     * @param clazz
     * @param id
     * @throws CoreDBException
     */
    public void deleteById(Class<?> clazz, Serializable id) throws CoreDBException;

    /**
     * Method to get database object list using object properties no blank and not null to
     * filter query
     * 
     * @param object
     * @return List
     * @throws CoreDBException
     */
    public List<?> getFindCriteria(Object object) throws CoreDBException;

    /**
     * Method to get database object list using object properties no blank and not null to
     * filter query and order by object property
     * 
     * @param object
     * @param orderBy
     * @return List
     * @throws CoreDBException
     */
    public List<?> getFindCriteria(Object object, String orderBy) throws CoreDBException;

    /**
     * Method to get database object list using object properties no blank and not null to
     * filter query, order by object property and compare is null property list
     * 
     * @param object
     * @param orderBy
     * @param restringeNull
     * @return List
     * @throws CoreDBException
     */
    public List<?> getFindCriteria(Object object, String orderBy, String restringeNull) throws CoreDBException;

    /**
     * Method to get database object list using object properties no blank and not null to
     * filter query, order by object property and truncate max result
     * 
     * @param object
     * @param maxResults
     * @param orderBy
     * @return List
     * @throws CoreDBException
     */
    public List<?> getFindCriteria(Object object, int maxResults, String orderBy) throws CoreDBException;

    /**
     * Method to get database object list using object properties no blank and not null to
     * filter query and truncate max result
     * 
     * @param object
     * @param maxResults
     * @return List
     * @throws CoreDBException
     */
    public List<?> getFindCriteria(Object object, int maxResults) throws CoreDBException;

    /**
     * Method to initialize hibernate proxy objects using Hiberante.initialize(object)
     * in the collection
     * 
     * @param collection
     * @throws CoreDBException
     */
    public void initializeCollection(Collection<?> collection) throws CoreDBException;

    /**
     * Method to initialize hibernate proxy objects using Hiberante.initialize(object)
     * 
     * @param object
     * @throws CoreDBException
     */
    public void initialize(Object object) throws CoreDBException;

    /**
     * Method return Id property name from class using ClassMetadata from SessionFactory
     * of Hibernate
     * 
     * @param clazz
     * @return String
     * @throws CoreDBException
     */
    public String getIdFieldName(Class<?> clazz) throws CoreDBException;

    /**
     * Method to save a collection using saveOrUpdate method
     * 
     * @param collection
     * @throws CoreDBException
     */
    public void saveCollection(Collection<?> collection) throws CoreDBException;

    /**
     * Method to get Oracle or MySql current date
     * 
     * @return Date
     * @throws CoreDBException
     */
    public Date getCurrentDate() throws CoreDBException;

    /**
     * Method to get List filled with map objects executing sql-query,
     * this method can be used to execute stored procedures and
     * object parameter can be Map or POJO this one will be reader
     * and setted in query. If you query didn't need any parameter
     * send null
     * 
     * @param namedQuery
     * @param object
     * @return List
     * @throws CoreDBException
     */
	public List<?> mapListar(String namedQuery, Object object) throws CoreDBException;

	/**
     * Method to get List filled with object arrays or class configured 
     * in sql-query to be executed, this method can be used to execute 
     * stored procedures and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param namedQuery
	 * @param object
	 * @return List
	 * @throws CoreDBException
	 */
	public List<?> listar(String namedQuery, Object object) throws CoreDBException;

	/**
     * Method to get List filled with objects created with clazz 
     * parameter executing sql-query, this method can be used to 
     * execute stored procedures.
	 * 
	 * @param namedQuery
	 * @param object
	 * @param clazz
	 * @return List
	 * @throws CoreDBException
	 */
	public List<?> listar(String namedQuery, Object object, Class<?> clazz) throws CoreDBException;

	/**
	 * Method to get Object this method execute and scalar result
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param namedQuery
	 * @param object
	 * @return Object
	 * @throws CoreDBException
	 */
	public Object executeProcedure(String namedQuery, Object object) throws CoreDBException;

	/**
	 * Method to get Object this method execute and return object from clazz
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param namedQuery
	 * @param object
	 * @param clazz
	 * @return
	 * @throws CoreDBException
	 */
	public Object executeProcedure(String namedQuery, Object object, Class<?> clazz) throws CoreDBException;

	/**
	 * Method to execute a executeUpdate method 
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param namedQuery
	 * @param object
	 * @return Object (String)
	 * @throws CoreDBException
	 */
	public Object executeVoidProcedure(String namedQuery, Object object) throws CoreDBException;

    /**
     * Method to get List filled with map objects executing sql-query,
     * this method can be used to execute stored procedures and
     * object parameter can be Map or POJO this one will be reader
     * and setted in query. If you query didn't need any parameter
     * send null
     * 
     * @param sqlQuery
     * @param object
     * @return List
     * @throws CoreDBException
     */
	public List<?> mapListarQuery(String sqlQuery, Object object) throws CoreDBException;

	/**
     * Method to get List filled with object arrays or class configured 
     * in sql-query to be executed, this method can be used to execute 
     * stored procedures and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param sqlQuery
	 * @param object
	 * @return List
	 * @throws CoreDBException
	 */
	public List<?> listarQuery(String sqlQuery, Object object) throws CoreDBException;

	/**
     * Method to get List filled with objects created with clazz 
     * parameter executing sql-query, this method can be used to 
     * execute stored procedures.
	 * 
	 * @param sqlQuery
	 * @param object
	 * @param clazz
	 * @return List
	 * @throws CoreDBException
	 */
	public List<?> listarQuery(String sqlQuery, Object object, Class<?> clazz) throws CoreDBException;

	/**
	 * Method to get Object this method execute and scalar result
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param sqlQuery
	 * @param object
	 * @return Object
	 * @throws CoreDBException
	 */
	public Object executeQuery(String sqlQuery, Object object) throws CoreDBException;

	/**
	 * Method to get Object this method execute and return object from clazz
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param sqlQuery
	 * @param object
	 * @param clazz
	 * @return Object
	 * @throws CoreDBException
	 */
	public Object executeQuery(String sqlQuery, Object object, Class<?> clazz) throws CoreDBException;

	/**
	 * Method to execute a executeUpdate method 
	 * and object parameter can be Map or POJO this 
     * one will be reader and setted in query. If you query didn't need 
     * any parameter send null
	 * 
	 * @param sqlQuery
	 * @param object
	 * @return Object (String)
	 * @throws CoreDBException
	 */
	public Object executeVoidQuery(String sqlQuery, Object object) throws CoreDBException;

	/**
	 * Method to execute procedures and returns values
	 * this method receive and map parameter with in parameters
	 * and out map with instances of classes to return for example
	 * 
	 * Map mapOUT = new HashMap();
	 * mapOUT.put("OUT_STRING", new String());
	 * mapOUT.put("OUT_LONG", new Long(0));
	 * 
	 * @param namedQuery
	 * @param mapIn
	 * @param mapOut
	 * @return Map same mapOut but with values filled
	 * @throws CoreDBException
	 */
	public Map<String, Object> executeProcedureOut(String namedQuery, Map<String, Object> mapIn, Map<String, Object> mapOut) throws CoreDBException;
}